package com.imageflowpro.image_flow_pro.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.imageflowpro.image_flow_pro.constant.JwtClaimsConstant;
import com.imageflowpro.image_flow_pro.context.BaseContext;
import com.imageflowpro.image_flow_pro.dto.*;
import com.imageflowpro.image_flow_pro.exception.BaseException;
import com.imageflowpro.image_flow_pro.mapper.MediaImageMapper;
import com.imageflowpro.image_flow_pro.mapper.VerificationCodeMapper;
import com.imageflowpro.image_flow_pro.po.*;
import com.imageflowpro.image_flow_pro.mapper.MediaOrderMapper;
import com.imageflowpro.image_flow_pro.properties.MinioProperties;
import com.imageflowpro.image_flow_pro.service.IMediaOrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.imageflowpro.image_flow_pro.service.IOrderCommentService;
import com.imageflowpro.image_flow_pro.utils.MinioUtil;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 订单主表 服务实现类
 * </p>
 *
 * @author 张家浩
 * @since 2025-05-07
 */
@Service
public class MediaOrderServiceImpl extends ServiceImpl<MediaOrderMapper, MediaOrder> implements IMediaOrderService {

    public static final String ORDER_TYPE_NORMAL="NORMAL";
    public static final String ORDER_TYPE_PREMIUM="PREMIUM";
    @Autowired
    private VerificationCodeMapper verificationCodeMapper;

    @Autowired
    private MinioUtil minioUtil;

    @Autowired
    private MinioProperties minioProperties;

    @Autowired
    private MediaImageMapper mediaImageMapper;





    @Override
    @Transactional
    public void userCreateOrder(CreateOrderDTO createOrderDTO) {
        //创建订单
        VerificationCode verificationCode = Db.lambdaQuery(VerificationCode.class)
                .eq(VerificationCode::getId, createOrderDTO.getVerificationId())
                .eq(VerificationCode::getUserId,BaseContext.getCurrentId())
                .one();
        if(verificationCode==null||!LocalDateTime.now().isBefore(verificationCode.getExpireAt())){
            throw new BaseException("该验证码已经过期");
        }
        verificationCodeMapper.delete(new LambdaQueryWrapper<VerificationCode>()
                .eq(VerificationCode::getId, createOrderDTO.getVerificationId())
        );
        List<MediaImage> mediaImageList = Db.lambdaQuery(MediaImage.class)
                .in(MediaImage::getId, createOrderDTO.getImageIdList())
                .eq(MediaImage::getUploadBy, BaseContext.getCurrentId())
                .eq(MediaImage::getVerificationId,verificationCode.getId())
                .list();
        if(mediaImageList.isEmpty()){
            throw new BaseException("订单为空");
        }
        MediaOrder mediaOrder = new MediaOrder();
        mediaOrder.setUserId(BaseContext.getCurrentId());
        mediaOrder.setIsValid(true);
        mediaOrder.setCurrentStatus(0);
        mediaOrder.setOrderType(ORDER_TYPE_NORMAL);
        if(verificationCode.getType().equals(VerificationCodeServiceImpl.SUPER_SUBMIT_ORDER_CODE_NAME)){
            mediaOrder.setOrderType(ORDER_TYPE_PREMIUM);
        }
        this.save(mediaOrder);
        mediaImageList.forEach(mediaImage -> {
            mediaImage.setVerificationId(-1L);
            mediaImage.setOrderId(mediaOrder.getId());
        });
        Db.updateBatchById(mediaImageList);
        OrderComment orderComment = new OrderComment();
        orderComment.setAdminId(-1L);
        orderComment.setOrderId(mediaOrder.getId());
        orderComment.setContent("创建当前订单使用的验证码："+verificationCode.getCode());
        Db.save(orderComment);
    }

    @Override
    @Transactional
    public UserGetOrderListDTO userGetOrderList(Long currentId) {
        List<String> orderStateList = getSystemConfigOrderStatusList();
        List<MediaOrder> orderList = this.lambdaQuery()
                .eq(MediaOrder::getUserId, currentId)
                .list();
        if(orderList.isEmpty()){
            UserGetOrderListDTO userGetOrderListDTO = new UserGetOrderListDTO();
            userGetOrderListDTO.setOrderList(new ArrayList<>());
            return userGetOrderListDTO;
        }
        Map<Long, UserGetOrderDTO> orderMap=new HashMap<>();
        orderList.forEach(mediaOrder -> {
            UserGetOrderDTO userGetOrderDTO = new UserGetOrderDTO();
            userGetOrderDTO.setOrderType(mediaOrder.getOrderType());
            userGetOrderDTO.setCreatedAt(mediaOrder.getCreatedAt());
            userGetOrderDTO.setId(mediaOrder.getId());
            userGetOrderDTO.setCurrentStatus(mediaOrder.getCurrentStatus());
            userGetOrderDTO.setImageIdList(new ArrayList<>());
            orderMap.put(mediaOrder.getId(), userGetOrderDTO);
        });
        List<MediaImage> mediaImageList = Db.lambdaQuery(MediaImage.class)
                .in(MediaImage::getOrderId, orderMap.keySet())
                .list();

        UserGetOrderListDTO userGetOrderListDTO = new UserGetOrderListDTO();
        userGetOrderListDTO.setOrderState(orderStateList);
        mediaImageList.forEach(mediaImage -> {
            Long imageId = mediaImage.getId();
            orderMap.get(mediaImage.getOrderId()).getImageIdList().add(imageId);
        });
        List<UserGetOrderDTO> userGetOrderDTOS = new ArrayList<>(orderMap.values());
        userGetOrderDTOS.sort(Comparator.comparing(UserGetOrderDTO::getCreatedAt).reversed());
        userGetOrderListDTO.setOrderList(userGetOrderDTOS);
        return userGetOrderListDTO;
    }

    @Override
    @Transactional
    public void updateSuperOrder(Long orderId, Boolean state) {
        MediaOrder mediaOrder = this.lambdaQuery()
                .eq(MediaOrder::getId, orderId)
                .eq(MediaOrder::getUserId, BaseContext.getCurrentId())
                .eq(MediaOrder::getOrderType,MediaOrderServiceImpl.ORDER_TYPE_PREMIUM)
                .one();
        if(mediaOrder==null){
            throw new BaseException("订单不存在");
        }
        if(!mediaOrder.getIsValid()){
            throw new BaseException("订单已经无效");
        }
        if(mediaOrder.getCurrentStatus()!=3){
            throw new BaseException("用户当前不能修改状态");
        }
        OrderStatusHistory orderStatusHistory = new OrderStatusHistory();

        orderStatusHistory.setOrderId(orderId);
        orderStatusHistory.setOldStatus(3);
        orderStatusHistory.setNewStatus(0);
        orderStatusHistory.setRemark("用户不满意订单，将订单打回");
        orderStatusHistory.setModifiedBy(BaseContext.getCurrentId());

        mediaOrder.setCurrentStatus(0);
        if(state){
            orderStatusHistory.setNewStatus(4);
            orderStatusHistory.setRemark("用户满意订单，确定签收");

            mediaOrder.setCurrentStatus(4);
        }
        this.updateById(mediaOrder);
        //记录订单状态变更表
        Db.save(orderStatusHistory);
    }

    @Override
    @Transactional
    public AdminGetOrderListDTO adminGetOrderList() {
        //获取系统变量
        List<String> orderStateList = getSystemConfigOrderStatusList();
        //准备封装容器
        Map<Long, AdminGetOrderDTO> orderMap=new HashMap<>();

        //获取订单信息
        List<MediaOrder> orderList = this.lambdaQuery()
                .list();
        if(orderList.isEmpty()){
            return new AdminGetOrderListDTO();
        }

        //获取用户所有信息
        List<User> userList = Db.lambdaQuery(User.class)
                .list();
        Map<Long,User> userMap=new HashMap<>();
        userList.forEach(user -> userMap.put(user.getId(),user));

        //封装订单信息
        orderList.forEach(mediaOrder -> {
            AdminGetOrderDTO adminGetOrderDTO = new AdminGetOrderDTO();
            adminGetOrderDTO.setOrderType(mediaOrder.getOrderType());
            adminGetOrderDTO.setCreatedAt(mediaOrder.getCreatedAt());
            adminGetOrderDTO.setId(mediaOrder.getId());
            adminGetOrderDTO.setCurrentStatus(mediaOrder.getCurrentStatus());
            adminGetOrderDTO.setIsValid(mediaOrder.getIsValid());
            adminGetOrderDTO.setImageIdList(new ArrayList<>());
            adminGetOrderDTO.setCommentList(new ArrayList<>());
            adminGetOrderDTO.setOrderStatusHistoryList(new ArrayList<>());
            Long lastModifiedBy = mediaOrder.getLastModifiedBy();
            adminGetOrderDTO.setLastModifiedName("无");
            if(lastModifiedBy!=null&&userMap.get(lastModifiedBy)!=null) {
                adminGetOrderDTO.setLastModifiedName(userMap.get(lastModifiedBy).getNickname());
            }
            adminGetOrderDTO.setPhone(userMap.get(mediaOrder.getUserId()).getPhone());
            adminGetOrderDTO.setUserName(userMap.get(mediaOrder.getUserId()).getNickname());
            //根据订单id封装订单信息
            orderMap.put(mediaOrder.getId(), adminGetOrderDTO);
        });
        //获取图片信息
        List<MediaImage> mediaImageList = Db.lambdaQuery(MediaImage.class)
                .in(MediaImage::getOrderId, orderMap.keySet())
                .list();

        //封装图片信息
        mediaImageList.forEach(mediaImage -> {
            Long imageId = mediaImage.getId();
            orderMap.get(mediaImage.getOrderId()).getImageIdList().add(imageId);
        });
        //获取评论信息
        List<OrderComment> commentList = Db.lambdaQuery(OrderComment.class)
                .orderByDesc(OrderComment::getCreatedAt)
                .list();

        //封装评论信息
        commentList.forEach(orderComment -> {
            Long orderId = orderComment.getOrderId();
            User user = userMap.get(orderComment.getAdminId());
            OrderCommentDTO orderCommentDTO=new OrderCommentDTO();
            BeanUtil.copyProperties(orderComment,orderCommentDTO);
            orderCommentDTO.setDelete(false);
            orderCommentDTO.setAdminName("未知");
            if(orderComment.getAdminId()==-1){
                orderCommentDTO.setAdminName("系统");
            }
            else if(user!=null) {
                orderCommentDTO.setDelete(Objects.equals(orderComment.getAdminId(), BaseContext.getCurrentId()) || JwtClaimsConstant.SUPER_ADMIN_ROLE.equals(user.getRole()));
                orderCommentDTO.setAdminName(user.getNickname());
            }
            orderMap.get(orderId).getCommentList().add(orderCommentDTO);
        });

        //获取订单状态历史
        List<OrderStatusHistory> orderStatusHistorieList = Db.lambdaQuery(OrderStatusHistory.class)
                .list();
        //封装历史状态
        orderStatusHistorieList.forEach(orderStatusHistory -> {
            OrderStatusHistoryDTO orderStatusHistoryDTO =new OrderStatusHistoryDTO();
            BeanUtil.copyProperties(orderStatusHistory,orderStatusHistoryDTO);
            orderStatusHistoryDTO.setModifiedByName("系统");
            if (orderStatusHistory.getModifiedBy()!=-1) {
                orderStatusHistoryDTO.setModifiedByName("未知");
                if (userMap.get(orderStatusHistory.getModifiedBy()) != null) {
                    orderStatusHistoryDTO.setModifiedByName(userMap.get(orderStatusHistory.getModifiedBy()).getNickname());

                }
            }
            orderMap.get(orderStatusHistory.getOrderId()).getOrderStatusHistoryList().add(orderStatusHistoryDTO);
        });

        //封装结果
        AdminGetOrderListDTO adminGetOrderListDTO= new AdminGetOrderListDTO();
        adminGetOrderListDTO.setOrderState(orderStateList);

        List<AdminGetOrderDTO> adminGetOrderDTOS = new ArrayList<>(orderMap.values());
        adminGetOrderDTOS.sort(Comparator.comparing(AdminGetOrderDTO::getCreatedAt).reversed());
        adminGetOrderListDTO.setOrderList(adminGetOrderDTOS);
        adminGetOrderListDTO.setTotal(adminGetOrderListDTO.getOrderList().size());
        return adminGetOrderListDTO;
    }

    @NotNull
    private static List<String> getSystemConfigOrderStatusList() {
        SystemConfig systemConfig = Db.lambdaQuery(SystemConfig.class)
                .eq(SystemConfig::getName, SystemConfigServiceImpl.ORDER_STATUS)
                .one();
        List<String> orderStateList = new ArrayList<>();
        try {
            // 创建 ObjectMapper 实例
            ObjectMapper objectMapper = new ObjectMapper();
            // 将 JSON 字符串解析为 JsonNode
            JsonNode rootNode = objectMapper.readTree(systemConfig.getValue());

            // 遍历所有字段的值并添加到列表中
            if (rootNode != null && rootNode.isObject()) {
                Iterator<Map.Entry<String, JsonNode>> fields = rootNode.fields();
                while (fields.hasNext()) {
                    Map.Entry<String, JsonNode> entry = fields.next();
                    orderStateList.add(entry.getValue().asText());
                }
            }
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        return orderStateList;
    }

    @Override
    @Transactional
    public void adminUpdateOrderStatus(Long orderId,Integer nowStatus) {
        MediaOrder mediaOrder = this.lambdaQuery()
                .eq(MediaOrder::getId, orderId)
                .one();
        if(mediaOrder==null){
            throw new BaseException("订单不存在");
        }
        if(!mediaOrder.getIsValid()){
            throw new BaseException("此订单已经被无效，要修改订单请激活订单");
        }
        if(mediaOrder.getCurrentStatus()+1!=nowStatus){
            throw new BaseException("订单状态不可用跳步");
        }
        if (mediaOrder.getCurrentStatus()==3){
            throw new BaseException("当前状态不允许管理员更改状态");
        }
        //获取系统变量
        List<String> orderStateList = getSystemConfigOrderStatusList();

        OrderStatusHistory orderStatusHistory = new OrderStatusHistory();
        orderStatusHistory.setOrderId(orderId);
        orderStatusHistory.setOldStatus(mediaOrder.getCurrentStatus());
        orderStatusHistory.setNewStatus(nowStatus);
        orderStatusHistory.setModifiedBy(BaseContext.getCurrentId());
        orderStatusHistory.setRemark("更新订单从"+orderStateList.get(mediaOrder.getCurrentStatus())+"状态到"+orderStateList.get(nowStatus)+"状态");
        Db.save(orderStatusHistory);

        mediaOrder.setCurrentStatus(nowStatus);
        mediaOrder.setLastModifiedBy(BaseContext.getCurrentId());
        this.updateById(mediaOrder);

    }

    @Override
    @Transactional
    public void adminUpdateOrderIsValid(Long orderId) {
        MediaOrder mediaOrder = this.getById(orderId);
        if(mediaOrder==null){
            throw new BaseException("订单不存在");
        }
        OrderStatusHistory orderStatusHistory = new OrderStatusHistory();
        if(mediaOrder.getIsValid()) {
            orderStatusHistory.setRemark("将当前订单设置为无效");
            orderStatusHistory.setOrderId(mediaOrder.getId());
            orderStatusHistory.setOldStatus(mediaOrder.getCurrentStatus());
            orderStatusHistory.setNewStatus(5);
            orderStatusHistory.setModifiedBy(BaseContext.getCurrentId());
            mediaOrder.setIsValid(false);
            mediaOrder.setCurrentStatus(5);
            mediaOrder.setLastModifiedBy(BaseContext.getCurrentId());
            this.updateById(mediaOrder);
            Db.save(orderStatusHistory);
            return;
        }
        boolean imageExists = Db.lambdaQuery(MediaImage.class)
                .eq(MediaImage::getOrderId, orderId)
                .exists();
        if(!imageExists){
            throw new BaseException("当前订单已经无效不能激活");
        }
        OrderStatusHistory history = Db.lambdaQuery(OrderStatusHistory.class)
                .eq(OrderStatusHistory::getOrderId, mediaOrder.getId())
                .ne(OrderStatusHistory::getOldStatus, 5)
                .eq(OrderStatusHistory::getNewStatus, 5)
                .orderByDesc(OrderStatusHistory::getCreatedAt)
                .list().get(0);
        mediaOrder.setCurrentStatus(history.getOldStatus());
        mediaOrder.setIsValid(true);
        mediaOrder.setLastModifiedBy(BaseContext.getCurrentId());
        history.setNewStatus(history.getOldStatus());
        history.setOldStatus(5);
        history.setId(null);
        history.setRemark("重新激活了当前订单");
        history.setModifiedBy(BaseContext.getCurrentId());
        history.setCreatedAt(null);
        this.updateById(mediaOrder);
        Db.save(history);
    }

    @Override
    @Transactional
    public void deleteOrderById(Long orderId) {
        MediaOrder mediaOrder = this.lambdaQuery()
                .eq(MediaOrder::getId, orderId)
                .one();
        if(mediaOrder==null){
            throw new BaseException("订单不存在");
        }
        if(mediaOrder.getCurrentStatus()!=5){
            throw new BaseException("要求作废的订单才可以");
        }
        mediaOrder.setLastModifiedBy(BaseContext.getCurrentId());
        OrderStatusHistory orderStatusHistory = new OrderStatusHistory();
        orderStatusHistory.setRemark("删除当前订单图片");
        orderStatusHistory.setOrderId(mediaOrder.getId());
        orderStatusHistory.setOldStatus(mediaOrder.getCurrentStatus());
        orderStatusHistory.setNewStatus(5);
        orderStatusHistory.setModifiedBy(BaseContext.getCurrentId());
        Db.save(orderStatusHistory);
        this.updateById(mediaOrder);
        List<MediaImage> deleteImageList = Db.lambdaQuery(MediaImage.class)
                .eq(MediaImage::getOrderId, orderId)
                .list();
        List<Long> deleteImageIdList = new ArrayList<>();
        deleteImageList.forEach(mediaImage -> {
            deleteImageIdList.add(mediaImage.getId());
            minioUtil.deleteFile(minioProperties.getBucketName(), mediaImage.getUploadBy()+"/"+mediaImage.getMinioName());
        });
        mediaImageMapper.deleteBatchIds(deleteImageIdList);

    }

}
